package it.unipd.fbaron.mind_reader_squared.activities;

import it.unipd.fbaron.mind_reader_squared.R;
import it.unipd.fbaron.mind_reader_squared.model.DataBaseHelper;
import it.unipd.fbaron.mind_reader_squared.model.ProfileLogic;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;

public class BaseActivity extends Activity implements OnInitListener {

	// TTS
	protected TextToSpeech tts = null;
	protected boolean isTtsReady = false;

	//Player for registered voices
	private MediaPlayer recordedPlayer;
	
	// Dialogs
	protected final int DIALOG_LOADING_ID = 0;

	// Database
	protected DataBaseHelper dbHelper;

	// Current profile options
	protected int profileId;
	protected String preferredLanguage;
	protected String preferredTts;
	protected boolean readAll = false;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// Take profile's ID passed in the intent object
		profileId = getIntent().getIntExtra("profile_id", -1);
		if (profileId < 0) {
			try {
				// If no ID passed with the intent we must verify with a cast if
				// the dynamic type is LoginActivity, the only one that can
				// start without a ID.
				@SuppressWarnings("unused")
				BaseActivity ba = (LoginActivity) this;
			} catch (Exception e) {
				finish();
			}
		}

		// Get DataBaseHelper instance (singleton)
		dbHelper = DataBaseHelper.getInstance(this);

		if (profileId > 0) {
			// Get language settings from user's profile, update locale
			// configuration of the system if necessary
			String[] result = ProfileLogic.getInstance(dbHelper).queryWithId(
					profileId,
					new String[] { "preferred_language", "preferred_tts" });
			preferredLanguage = result[0];
			preferredTts = result[1];

			Resources res = getResources();
			Configuration config = new Configuration(res.getConfiguration());
			config.locale = new Locale(preferredLanguage);
			res.updateConfiguration(config, null);

			result = ProfileLogic.getInstance(dbHelper).queryWithId(profileId,
					new String[] { "read_all" });
			if (Integer.parseInt(result[0]) > 0) {
				readAll = true;
			}
		}

		// Create tts object using this (onInit) as callback for the creation
		// completion event.
		tts = new TextToSpeech(this, this);
		
		//Prepare recordedPlayer to reproduce sounds recorded by the user
		recordedPlayer = new MediaPlayer();
		recordedPlayer.setOnPreparedListener(new OnPreparedListener() {
			
			@Override
			public void onPrepared(MediaPlayer mp) {
				mp.start();
			}
		});
		recordedPlayer.setOnCompletionListener(new OnCompletionListener() {
			
			@Override
			public void onCompletion(MediaPlayer mp) {
				mp.stop();
				mp.reset();
			}
		});
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		dbHelper.close();
		if (tts != null)
			tts.shutdown();
		
		if (recordedPlayer != null) {
			recordedPlayer.release();
		}
	}

	@Override
	protected void onPause() {
		super.onPause();

		if (tts != null)
			tts.shutdown();
		tts = null;
		isTtsReady = false;
		
		if (recordedPlayer != null) {
			recordedPlayer.release();
			recordedPlayer = null;
		}
	}

	@Override
	protected void onResume() {
		super.onResume();

		if (tts == null) {
			tts = new TextToSpeech(this, this);

			// Reset language settings because this activity could be started by
			// a BACK action from ManageProfileActivity where settings has been
			// changed.
			if (profileId > 0) {
				String[] result = ProfileLogic.getInstance(dbHelper)
						.queryWithId(
								profileId,
								new String[] { "preferred_language",
										"preferred_tts" });
				preferredLanguage = result[0];
				preferredTts = result[1];

				Resources res = getResources();
				Configuration config = new Configuration(res.getConfiguration());
				config.locale = new Locale(preferredLanguage);
				res.updateConfiguration(config, null);
			}
		}
		
		recordedPlayer = new MediaPlayer();
		recordedPlayer.setOnPreparedListener(new OnPreparedListener() {
			
			@Override
			public void onPrepared(MediaPlayer mp) {
				mp.start();
			}
		});
		recordedPlayer.setOnCompletionListener(new OnCompletionListener() {
			
			@Override
			public void onCompletion(MediaPlayer mp) {
				mp.stop();
				mp.reset();
			}
		});
	}

	/*
	 * Callback function of TextToSpeech object which is called when tts is
	 * completely created.
	 */
	@Override
	public void onInit(int status) {
		if (preferredTts == null)
			return;

		// TTS is ready!
		isTtsReady = true;
		if ((tts.isLanguageAvailable(new Locale(preferredTts)) == TextToSpeech.LANG_AVAILABLE)
				|| (tts.isLanguageAvailable(new Locale(preferredTts)) == TextToSpeech.LANG_COUNTRY_AVAILABLE)) {
			tts.setLanguage(new Locale(preferredTts));
			isTtsReady = true;
		}
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		Dialog dialog;
		switch (id) {
		case DIALOG_LOADING_ID:
			ProgressDialog progressDialog = new ProgressDialog(this);
			progressDialog.setTitle("");
			progressDialog.setMessage(getResources()
					.getString(R.string.loading));
			progressDialog.setIndeterminate(true);
			dialog = progressDialog;
			break;
		default:
			dialog = null;
		}
		return dialog;
	}

	/************************************
	 ************** UTILS ***************
	 ***********************************/

	/*
	 * Read the text in input after a given delay
	 */
	protected void readText(final String str, final long delay) {
		new Timer().schedule(new TimerTask() {

			@Override
			public void run() {
				if (isTtsReady) {
					tts.speak(str, TextToSpeech.QUEUE_FLUSH, null);
				}
			}
		}, delay);
	}

	/*
	 * Load an image from application resources or android gallery or another
	 * location from file-system. Return a Drawable object.
	 */
	protected Drawable getSymbolImage(int resource, String path) {
		if (resource > 0) {
			return getResources().getDrawable(resource);
		} else {
			try {
				Bitmap b = MediaStore.Images.Media.getBitmap(
						getContentResolver(), Uri.parse(path));
				BitmapDrawable bd = new BitmapDrawable(b);
				return bd;
			} catch (FileNotFoundException e1) {
				Drawable d = Drawable.createFromPath(path);
				if (d != null)
					return d;
				else
					return getResources().getDrawable(
							R.drawable.m1_image_not_found);
			} catch (IOException e1) {
				return getResources()
						.getDrawable(R.drawable.m1_image_not_found);
			} catch (OutOfMemoryError e2) {
				return getResources()
						.getDrawable(R.drawable.m1_image_not_found);
			}
		}
	}
	
	/*
	 * Start the sound, from text or record, given in input.
	 */
    protected void startSymbolSound(int soundChoise, String pathOrText) {
    	if (soundChoise == 0) {
    		readText(pathOrText, 500);
    	}
    	else {
	        Uri uri = Uri.parse(pathOrText);
			recordedPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			try {
				recordedPlayer.setDataSource(this, uri);
				recordedPlayer.prepareAsync();
			} catch (Exception e) {
				e.printStackTrace();
			}
    	}
    }
}
